package com.chen.androidstudy.activity;

/**
 * @Author: CHong
 * @CreateDate: 2024/6/13 0013
 * @Description:
 */

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.chen.androidstudy.R;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理实现事件注入(原理)
 */
public class ProxyActivity extends AppCompatActivity {

    private Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proxy);
        bt = (Button) findViewById(R.id.bt);
//        proxySetOnclick();
        proxySetOnclick2();
    }

    //通过代理为button设置监听
    private void proxySetOnclick() {
        try {
            //反射获得Button的setOnclicListen方法(参数1:方法名;2:方法参数类)
            Method setOnClickListener = bt.getClass().getMethod("setOnClickListener", View.OnClickListener.class);
            //获得真实回调的方法(后期可以用注解获得这里hardCode了)
            Method realClick = this.getClass().getMethod("realClick", View.class);
            //创建一个代理
            ProxyHandle handle = new ProxyHandle(this, realClick);
            //设置代理 返回的是对应的接口 (OnClickListener实例对象)
            Object proxyObj = Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class[]{View.OnClickListener.class}, handle);

            //调用对应View的设置监听方法 之后会到代理handle里去(对象可以用注解获得这里暂不分析)
            setOnClickListener.invoke(bt, proxyObj);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private void proxySetOnclick2() {
        try {
            Class<ProxySecordActivity> activityClass = ProxySecordActivity.class;
            //反射获得Button的setOnclicListen方法(参数1:方法名;2:方法参数类)
            Method setOnClickListener = activityClass.getMethod("onTakePhoto");
//            for (Field field : activityClass.getFields()) {
//                Log.e("chen", field.getName());
//            }
            setOnClickListener.invoke(null);
            //获得真实回调的方法(后期可以用注解获得这里hardCode了)
            Method realClick = this.getClass().getMethod("realClick", View.class);
            //创建一个代理
            ProxyHandle handle = new ProxyHandle(this, realClick);
            //设置代理 返回的是对应的接口 (OnClickListener实例对象)
            Object proxyObj = Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class[]{View.OnClickListener.class}, handle);
            Proxy.newProxyInstance(ProxySecordActivity.class.getClassLoader(), new Class[]{setOnClickListener.getClass()}, handle);
            //调用对应View的设置监听方法 之后会到代理handle里去(对象可以用注解获得这里暂不分析)
//            setOnClickListener.invoke(proxyObj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //真实回调方法
    public void realClick(View v) {
        Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show();
    }

    /**
     * Created by 05 on 2017/3/1.
     * qq:799135138
     */

    public class ProxyHandle implements InvocationHandler {
        private Object realObj;
        private Method realMethod;

        public ProxyHandle(Object realObj, Method realMethod) {
            this.realObj = realObj;
            this.realMethod = realMethod;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //如果真实对象跟方法都不为null 则直接返回真是方法(这里真实方法必须跟接口方法参数保存一致)
            if (realObj != null && realMethod != null) {
                return realMethod.invoke(realObj, args);
            } else {
                return method.invoke(proxy, args);
            }
        }
    }
}
